import sqlite3


def create_table(conn, cursor):
    """创建users表（若不存在）"""
    try:
        create_user_sql = '''
                          CREATE TABLE IF NOT EXISTS users(
                              id INTEGER PRIMARY KEY AUTOINCREMENT,
                              name TEXT NOT NULL,
                              age INTEGER,
                              email TEXT UNIQUE  -- 邮箱唯一约束
                          )
                          '''
        cursor.execute(create_user_sql)
        print("✅ 表创建成功（或已存在）")
    except sqlite3.Error as e:
        print(f"❌ 创建表失败：{e}")
        raise  # 抛出异常，由主逻辑统一回滚


def insert_data(conn, cursor, data_list):
    """批量插入用户数据（data_list格式：[(name, age, email), ...]）"""
    if not data_list:
        print("❌ 插入失败：数据列表为空")
        return

    try:
        # 新增 OR IGNORE 避免邮箱重复导致插入失败
        insert_user_sql = "INSERT OR IGNORE INTO users (name, age, email) VALUES (?, ?, ?)"
        cursor.executemany(insert_user_sql, data_list)
        # 无需手动 commit，with 正常结束会自动提交
        print(f"✅ 数据插入成功，新增 {cursor.rowcount} 条数据（已忽略重复邮箱）")
    except sqlite3.IntegrityError as e:
        print(f"❌ 插入失败：数据完整性错误（可能邮箱重复）：{e}")
        raise  # 抛出异常，由主逻辑统一回滚
    except sqlite3.Error as e:
        print(f"❌ 插入数据失败：{e}")
        raise


def delete_data(conn, cursor, id_list):
    """删除用户（支持单条/批量，id_list格式：[id1] 或 [id1, id2, ...]）"""
    if not id_list:
        print("❌ 删除失败：ID列表为空")
        return

    try:
        # 批量删除（适配单条/多条ID）
        delete_user_sql = "DELETE FROM users WHERE id IN ({})".format(','.join('?' * len(id_list)))
        cursor.execute(delete_user_sql, id_list)
        if cursor.rowcount > 0:
            print(f"✅ 数据删除成功，共删除 {cursor.rowcount} 条数据")
        else:
            print("❌ 删除失败：未找到匹配ID的用户")
    except sqlite3.Error as e:
        print(f"❌ 删除失败：{e}")
        raise


def update_data(conn, cursor, new_name, target_id):
    """根据ID更新用户名"""
    try:
        update_user_sql = "UPDATE users SET name = ? WHERE id = ?"
        cursor.execute(update_user_sql, (new_name, target_id))
        if cursor.rowcount > 0:
            print(f"✅ 数据更新成功，共更新 {cursor.rowcount} 条数据")
        else:
            print("❌ 更新失败：未找到匹配ID的用户")
    except sqlite3.Error as e:
        print(f"❌ 更新失败：{e}")
        raise


def select_data(cursor, condition_sql="", params=()):
    """查询用户数据（支持全查/条件查）"""
    try:
        query_sql = f"SELECT id, name, age, email FROM users {condition_sql}"
        cursor.execute(query_sql, params)
        results = cursor.fetchall()

        # 格式化输出
        if condition_sql:
            print(f"\n📋 条件查询结果（{condition_sql}，参数：{params}）：")
        else:
            print("\n📋 所有用户数据：")

        if results:
            for user in results:
                print(f"ID: {user[0]}, 姓名: {user[1]}, 年龄: {user[2]}, 邮箱: {user[3]}")
        else:
            print("⚠️  未查询到符合条件的用户")
        return results
    except sqlite3.Error as e:
        print(f"❌ 查询失败：{e}")
        return []


if __name__ == '__main__':
    db_path = 'test_def_database.db'

    # 核心：用 with 管理连接，自动处理打开/关闭和事务提交
    with sqlite3.connect(db_path) as conn:
        cursor = conn.cursor()  # 在 with 块内创建游标，与当前连接绑定
        print("✅ 数据库连接成功（with 自动管理）")

        try:
            # 执行所有操作（函数调用逻辑不变）
            create_table(conn, cursor)

            # 插入数据
            user_list = [
                ("Bob", 30, "bob@example.com"),
                ("张三", 40, "zhangsan@example.com"),
                ("Alice", 25, "alice@example.com")
            ]
            insert_data(conn, cursor, user_list)

            # 全查数据
            select_data(cursor)

            # 条件查询（年龄>28的用户）
            select_data(cursor, "WHERE age > ?", (28,))

            # 更新数据（ID=1 → 用户名改为"Bob_Updated"）
            update_data(conn, cursor, new_name="Bob_Updated", target_id=1)

            # 验证更新结果
            select_data(cursor, "WHERE id = ?", (1,))

            # 删除数据（删除ID=2的用户）
            delete_data(conn, cursor, id_list=[2])

            # 验证删除结果
            select_data(cursor)

        except sqlite3.Error as e:
            # 所有异常统一捕获，手动回滚事务
            conn.rollback()
            print(f"\n❌ 程序执行出错，已回滚事务：{e}")

    # 退出 with 块后，连接自动关闭，无需手动调用 conn.close()
    print("\n✅ 程序结束，with 已自动关闭数据库连接")